package com.woniuxy.proxy;


import com.sun.xml.internal.bind.v2.TODO;
import com.woniuxy.aspect.Aspect;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import org.jetbrains.annotations.NotNull;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;


/**
 * @author: ideaAdmin
 * Date: 2022/1/20:11:32
 * Description:代理类工厂
 */

public class JdkProxyFactory {
    private static Aspect aspect = new Aspect();



    /**
     * @Author ideaAdmin
     * TODO:jdk实现动态代理方法
     * @Date 14:59 2022/1/20
     * * @param serviceType 传入service的class
     * * @return T 返回传入的类型
     **/

    public static <T> T getObjectProxy(Class<T> serviceType) {

        return (T) Proxy.newProxyInstance(serviceType.getClassLoader(), serviceType.getInterfaces(),
                //代理对象 调用方法 方法参数
                (Object proxy, Method method, Object[] args) -> {

                    aspect.beforeMethod();

                    Object invoke = null;
                    try {
                        invoke = method.invoke(serviceType.newInstance(), args);
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    } catch (InvocationTargetException e) {
                        Throwable proxyException = e.getTargetException();
                        proxyException.printStackTrace();
                    }

                    aspect.afterMethod();

                    return invoke;
                });
    }

    /**
     * @Author ideaAdmin
     * TODO:
     * @Date 15:01 2022/1/20
     * * @param serviceType
     * * @return T
     **/
    public static <T> T getEnhancerProxy(Class<T> serviceType) {
        return (T) Enhancer.create(serviceType, serviceType.getInterfaces(),  (MethodInterceptor)
                (Object proxy, Method method, Object[] args, MethodProxy methodProxy) -> {
                    aspect.beforeMethod();
                    Object invoke = null;
                    try {
                        invoke = method.invoke(serviceType.newInstance(), args);
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    } catch (InvocationTargetException e) {
                        //获取cglib的捕获异常
                        Throwable proxyException = e.getTargetException();
                        proxyException.printStackTrace();
                    }
                    aspect.afterMethod();
                    return invoke;
                });
    }

}
